package com.atguigu.tingshu.album.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.nacos.common.utils.StringUtils;
import com.atguigu.tingshu.album.config.VodConstantProperties;
import com.atguigu.tingshu.album.mapper.AlbumInfoMapper;
import com.atguigu.tingshu.album.mapper.TrackInfoMapper;
import com.atguigu.tingshu.album.mapper.TrackStatMapper;
import com.atguigu.tingshu.album.service.TrackInfoService;
import com.atguigu.tingshu.album.service.VodService;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.model.album.AlbumInfo;
import com.atguigu.tingshu.model.album.TrackInfo;
import com.atguigu.tingshu.model.album.TrackStat;

import com.atguigu.tingshu.query.album.TrackInfoQuery;
import com.atguigu.tingshu.user.client.UserFeignClient;
import com.atguigu.tingshu.vo.album.*;
import com.atguigu.tingshu.vo.user.UserInfoVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;


import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@Service
@SuppressWarnings({"all"})
public class TrackInfoServiceImpl extends ServiceImpl<TrackInfoMapper, TrackInfo> implements TrackInfoService {

    @Autowired
    private TrackInfoMapper trackInfoMapper;
    @Autowired
    private AlbumInfoMapper albumInfoMapper;
    @Autowired
    private TrackStatMapper trackStatMapper;
    @Autowired
    private VodService vodService;
    @Autowired
    private UserFeignClient userFeignClient;

    /**
     * 保存声音信息
     *
     * @param trackInfoVo
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveTrackInfo(Long userId, TrackInfoVo trackInfoVo) {
        //1 保存声音表
        TrackInfo trackInfo = BeanUtil.copyProperties(trackInfoVo, TrackInfo.class);
        trackInfo.setUserId(userId);
        //2 添加专辑表中的声音数量
        AlbumInfo albumInfo = albumInfoMapper.selectById(trackInfoVo.getAlbumId());
        albumInfo.setIncludeTrackCount(albumInfo.getIncludeTrackCount() + 1);
        trackInfo.setOrderNum(albumInfo.getIncludeTrackCount() + 1);
        //图片url
        if (StringUtils.isBlank(trackInfo.getCoverUrl())) {
            trackInfo.setCoverUrl(albumInfo.getCoverUrl());
        }
						/*try{
							// 实例化一个认证对象，入参需要传入腾讯云账户 SecretId 和 SecretKey，此处还需注意密钥对的保密
							Credential cred = new Credential(vodConstantProperties.getSecretId(), vodConstantProperties.getSecretKey());
							// 实例化要请求产品的client对象,clientProfile是可选的
							VodClient client = new VodClient(cred, vodConstantProperties.getRegion());
							// 实例化一个请求对象,每个接口都会对应一个request对象
							DescribeMediaInfosRequest req = new DescribeMediaInfosRequest();
							String[] fileIds1 = {trackInfoVo.getMediaFileId()};
							req.setFileIds(fileIds1);

							// 返回的resp是一个DescribeMediaInfosResponse的实例，与请求对象对应
							DescribeMediaInfosResponse resp = client.DescribeMediaInfos(req);
							resp*/

        //3 媒体时长，媒体的id和url，媒体的大小,类型
        TrackMediaInfoVo mediaInfoVo = vodService.getMediaInfo(trackInfo.getMediaFileId());
        if (mediaInfoVo != null) {
            trackInfo.setMediaDuration(BigDecimal.valueOf(mediaInfoVo.getDuration()));
            trackInfo.setMediaSize(mediaInfoVo.getSize());
            trackInfo.setMediaType(mediaInfoVo.getType());
        }

        //4 保存声音
        trackInfoMapper.insert(trackInfo);
        albumInfoMapper.updateById(albumInfo);

        //5 保存声音统计表
        this.saveTrackStat(trackInfo.getId(), SystemConstant.TRACK_STAT_PLAY, 0);
        this.saveTrackStat(trackInfo.getId(), SystemConstant.TRACK_STAT_COLLECT, 0);
        this.saveTrackStat(trackInfo.getId(), SystemConstant.TRACK_STAT_PRAISE, 0);
        this.saveTrackStat(trackInfo.getId(), SystemConstant.TRACK_STAT_COMMENT, 0);

        //5.TODO 调用点播平台发起音频文件审核任务（异步审核）
        String reviewTaskId = vodService.reviewTask(trackInfo.getMediaFileId());
        if (reviewTaskId != null) {
            trackInfo.setReviewTaskId(reviewTaskId);
            trackInfo.setStatus(SystemConstant.TRACK_STATUS_REVIEWING);
            trackInfoMapper.updateById(trackInfo);
        }

    }

    /**
     * 保存声音统计
     *
     * @param trackId
     * @param statType
     * @param statNum
     */
    @Override
    public void saveTrackStat(Long trackId, String statType, int statNum) {
        TrackStat trackStat = new TrackStat();
        trackStat.setTrackId(trackId);
        trackStat.setStatType(statType);
        trackStat.setStatNum(statNum);
        trackStatMapper.insert(trackStat);
    }


    /**
     * 分页查询声音信息
     *
     * @param pageInfo
     * @param trackInfoQuery
     * @return
     */
    @Override
    public Page<TrackListVo> findUserTrackPage(Page<TrackListVo> pageInfo, TrackInfoQuery trackInfoQuery) {
        return trackInfoMapper.findUserTrackPage(pageInfo, trackInfoQuery);
    }

    /**
     * 回显
     *
     * @param id
     * @return
     */
    @Override
    public TrackInfo getTrackInfo(Long id) {
        TrackInfo trackInfo = trackInfoMapper.selectById(id);
        return trackInfo;
    }

    /**
     * 修改声音数据
     *
     * @param id
     * @param trackInfoVo
     */
    @Override
    public void updateTrackInfo(Long id, TrackInfoVo trackInfoVo) {
        //1 获取ID查看各个是否更新
        TrackInfo trackInfo = BeanUtil.copyProperties(trackInfoVo, TrackInfo.class);
        TrackInfo oldTrackInfo = trackInfoMapper.selectById(id);
        if (!trackInfo.getAlbumId().equals(oldTrackInfo.getAlbumId())) {
            oldTrackInfo.setAlbumId(trackInfo.getAlbumId());
        }
        if (!trackInfo.getMediaFileId().equals(oldTrackInfo.getMediaFileId())) {
            TrackMediaInfoVo mediaInfoVo = vodService.getMediaInfo(trackInfo.getMediaFileId());
            if (mediaInfoVo != null) {
                oldTrackInfo.setMediaDuration(BigDecimal.valueOf(mediaInfoVo.getDuration()));
                oldTrackInfo.setMediaSize(mediaInfoVo.getSize());
                oldTrackInfo.setMediaType(mediaInfoVo.getType());
            }
            oldTrackInfo.setMediaFileId(trackInfo.getMediaFileId());
            //1.4 从点播平台删除旧的音频文件
            vodService.deleteMedia(oldTrackInfo.getMediaFileId());

        }
        oldTrackInfo.setTrackTitle(trackInfo.getTrackTitle());
        oldTrackInfo.setTrackIntro(trackInfo.getTrackIntro());
        oldTrackInfo.setTrackRichIntro(trackInfo.getTrackRichIntro());
        oldTrackInfo.setCoverUrl(trackInfo.getCoverUrl());
        oldTrackInfo.setIsOpen(trackInfo.getIsOpen());
        trackInfoMapper.updateById(oldTrackInfo);

    }

    /**
     * 删除声音数据
     *
     * @param id
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void removeTrackInfo(Long id) {
        //1 删除声音数据，把后面的声音数据序号往前移一位
        TrackInfo trackInfo = trackInfoMapper.selectById(id);
        Long albumId = trackInfo.getAlbumId();
        Integer orderNum = trackInfo.getOrderNum();
        trackInfoMapper.deleteById(id);
        trackInfoMapper.update(null, new LambdaUpdateWrapper<TrackInfo>()
                .eq(TrackInfo::getAlbumId, albumId)
                .gt(TrackInfo::getOrderNum, orderNum)
                .setSql("order_num = order_num - 1"));
        //2 删除声音统计数据
        trackStatMapper.delete(new LambdaQueryWrapper<TrackStat>().eq(TrackStat::getTrackId, id));
        //3 从专辑删除音频文件
        vodService.deleteMedia(trackInfo.getMediaFileId());
        //4 减少专辑的音频数量
        albumInfoMapper.update(null, new LambdaUpdateWrapper<AlbumInfo>()
                .eq(AlbumInfo::getId, albumId)
                .setSql("include_track_count = include_track_count - 1"));

    }

    /**
     * 专辑详情页查询
     *
     * @param pageInfo
     * @param albumId
     * @return
     */
    @Override
    public Page<AlbumTrackListVo> findAlbumTrackList(Page<AlbumTrackListVo> pageInfo, Long albumId, Long userId) {
        //1 获取声音基本信息
        Page<AlbumTrackListVo> pageResult = trackInfoMapper.findAlbumTrackList(pageInfo, albumId);

        //2 获取专辑信息，统计免费的集数
        AlbumInfo albumInfo = albumInfoMapper.selectById(albumId);
        String payType = albumInfo.getPayType();
        Integer tracksForFree = albumInfo.getTracksForFree();
        //3 判断用户是否登录
        if (userId == null) {
            if (SystemConstant.ALBUM_PAY_TYPE_VIPFREE.equals(payType) || SystemConstant.ALBUM_PAY_TYPE_REQUIRE.equals(payType)){
                //3.1 将不免费的声音置为付费标识
                pageResult.getRecords()
                        .stream()
                        .filter(i -> i.getOrderNum() > tracksForFree)
                        .forEach(i -> i.setIsShowPaidMark(true));
            return pageResult;}
        } else {
            //3.2 判断用户是否是会员
            UserInfoVo userInfo = userFeignClient.getUserInfoVo(userId).getData();
            Date vipExpireTime = userInfo.getVipExpireTime();
            //4.4.1 获取本页中需要检查购买情况声音（去掉免费试听）
            List<Long> needCheckBuyStateTrackIds =
                    pageInfo.getRecords()
                            .stream()
                            .filter(albumTrackListVo -> albumTrackListVo.getOrderNum() > tracksForFree)
                            .map(AlbumTrackListVo::getTrackId)
                            .collect(Collectors.toList());
            //方法一：逐个处理
           /* //3.2.1  专辑是vip免费
            if (SystemConstant.ALBUM_PAY_TYPE_VIPFREE.equals(payType)) {
                //3.2.1.1 用户是会员，专辑是vip免费，将所有声音置为免费(默认返回全为可看)
                //3.2.1.2 用户不是会员，专辑是vip免费，将不免费的声音置为付费标识
                if (1 != userInfo.getIsVip().intValue() || vipExpireTime.before(new Date())) {
                    Map<Long, Integer> mapResult = userFeignClient
                            .userIsPaidTrack(userId,
                                    albumId,
                                    needCheckBuyStateTrackIds).getData();
                        pageResult.getRecords()
                                .stream()
                                .filter(albumTrackListVo -> albumTrackListVo.getOrderNum() > tracksForFree)
                                .forEach(i -> i.setIsShowPaidMark(mapResult.get(i.getTrackId()) != 1));
                        return pageResult;

                }
                //3.2.2 专辑是付费,不用区分用户是否是会员
            } else if (SystemConstant.ALBUM_PAY_TYPE_REQUIRE.equals(payType)) {
                Map<Long, Integer> mapResult = userFeignClient
                        .userIsPaidTrack(userId,
                        albumId,
                        needCheckBuyStateTrackIds).getData();
                    pageResult.getRecords()
                            .stream()
                            .filter(albumTrackListVo -> albumTrackListVo.getOrderNum() > tracksForFree)
                            .forEach(i -> i.setIsShowPaidMark(mapResult.get(i.getTrackId()) != 1));
                    return pageResult;

            }*/
            //方法二:设置flag
            boolean flag = false;
            if (SystemConstant.ALBUM_PAY_TYPE_VIPFREE.equals(payType)){
                flag = 1 != userInfo.getIsVip().intValue() || vipExpireTime.before(new Date());
            }else if (SystemConstant.ALBUM_PAY_TYPE_REQUIRE.equals(payType)){
                flag = true;
            }
            if(flag){
                Map<Long, Integer> mapResult = userFeignClient
                        .userIsPaidTrack(userId,
                                albumId,
                                needCheckBuyStateTrackIds).getData();
                pageResult.getRecords()
                        .stream()
                        .filter(albumTrackListVo -> albumTrackListVo.getOrderNum() > tracksForFree)
                        .forEach(i -> i.setIsShowPaidMark(mapResult.get(i.getTrackId()) != 1));
                return pageResult;
            }

        }
        return pageResult;
    }

    /**
     * 查询声音统计信息
     * @param trackId
     * @return
     */
    @Override
    public TrackStatVo getTrackStatVo(Long trackId) {
        return trackInfoMapper.getTrackStatVo(trackId);
    }
}
